import json
import logging
import os.path
import time

import numpy as np
import pandas as pd
from websocket import create_connection

from plotter import MultiYAxisPlot

logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
                    datefmt='%Y-%m-%d %H:%M:%S ', level=logging.INFO)
logger = logging.getLogger(__name__)

# 定义文件输入路径
excel_file_path = r"算例1.xls"
# excel_file_path = r"算例2xls"
# excel_file_path = r"算例3.xls"
# excel_file_path = r"算例4.xls"
# excel_file_path = r"算例5.xls"
websocket_url = "ws://10.1.16.50:11051/ws/dynamic"  # 替换为实际的WebSocket服务器URL

base_file_name = os.path.basename(excel_file_path)
message = str({'uName': "cupb", 'pName': base_file_name})

# 开始计时
start_time = time.time()

# 创建 WebSocket 连接
ws = create_connection(websocket_url)
connection_status = ws.recv()  # 接收服务器回复的消息
bytes_sent1 = ws.send(message)
initialization_status = ws.recv()
initialization_finish_check = ws.recv()

colors = ["blue", "orange", "green", "red", "purple"]
is_first_iteration = True  # 用于标记是否是第一次接收到数据

df_datas = []
df_data0 = pd.DataFrame()
# 定义输出变量名称
series = ['myProfile', 'myProfileE', 'myProfileHl', 'myProfileP', 'myProfileT', 'myProfileTg', 'myProfileTl',
          'myProfileV', 'myProfileVg', 'myProfileVl', 'myCumVolL']
series_dict = {"myProfile": "里程 m", "myProfileE": "高程 m", "myProfileHl": "持液率", "myProfileP": "压力 Pa",
               "myProfileT": "混合温度 K", "myProfileTg": "气相温度 K", "myProfileTl": "液相温度 K",
               'myProfileV': "混合流速 m/s", 'myProfileVg': "气相流速 m/s", 'myProfileVl': "液相流速 m/s",
               "myCumVolL": "积液量"}
seriesVars = [{} for _ in series]

totalT = 20000

if bytes_sent1 != -1:
    logger.info(message + f"send计算模型指定成功: {bytes_sent1}")

    bytes_sent2 = ws.send("simStart")
    last_iteration_time = []  # 初始化上一次迭代时间的变量
    if bytes_sent2 != -1:
        logger.info(f"开始计算: {bytes_sent2}")
        i = 1
        while True:
            result4 = ws.recv()
            result4j = json.loads(result4)  # 获取 json 格式的数据结果
            logger.info(result4j)

            data = result4j['data']
            if data == 'Sim Stop.':
                ws.send("simStop")
                logger.info("计算已结束")
                break

            if len(data) == 0:
                logger.error("计算错误，无结果")
                bytes_sent4 = ws.send("simStop")
                if bytes_sent4 != -1:
                    logger.info("计算已停止")
                break

            timeRecord = float(data['myCostT'])

            # 初始化实时绘图
            xs = []
            ys = []
            labels = []
            # 数组中最大数据长度
            maxLen = len(data[series[0]])
            for paramStr in series:
                if paramStr in data:
                    # 补充数据
                    deltaLen = maxLen - len(data[paramStr])
                    for _ in range(deltaLen):
                        data[paramStr].append(data[paramStr][-1])
                    if paramStr != series[0]:
                        labels.append(series_dict[paramStr])
                        ys.append(np.array(data[paramStr]))
                    else:
                        xs.append(data[paramStr])
            # 初始化绘图曲线
            if is_first_iteration:
                # 创建多Y轴折线图
                title = f"模拟时间: {round(timeRecord, 2)} s"
                plot = MultiYAxisPlot(xs[0], ys, labels)
                # real_time_plot.initialize_lines(len(y_series))
                # # 启动实时绘图线程
                # plot_thread = Thread(target=plot.show)
                # plot_thread.start()
                is_first_iteration = False

            # 更新实时绘图
            new_title = f"模拟时间: {round(timeRecord, 2)} s"
            plot.setTitle(new_title)
            plot.update(ys)

            # 暂停一下
            # time.sleep(0.2)

            # 判断上一次迭代时间与本次迭代时间是否相同
            if data['myCostT'] == last_iteration_time:
                ws.send("simStop")
                logger.info("计算已结束")
                break
            else:
                # 如果上一次迭代时间与本次迭代时间不同，则更新上次迭代时间
                last_iteration_time = data['myCostT']

            if data['myCostT'] >= totalT:
                ws.send("simStop")
                logger.info("计算已结束")
                break
        else:
            logger.info(" simStart 开始计算失败")

else:
    print(message + "send 中 计算模型指定失败")

# 关闭 WebSocket 连接
ws.close()

end_time = time.time()
execution_time = end_time - start_time

for v in range(len(seriesVars)):
    df_data = pd.DataFrame(seriesVars[v])
    df_datas.append(df_data)

excel_file_path = r"结果.xls"

# 保存模拟结果
with pd.ExcelWriter(excel_file_path, engine='xlsxwriter') as writer:
    for i in range(len(df_datas)):
        df_datas[i].to_excel(writer, sheet_name=series[i], index=False)

    logger.error('结果已输出至' + excel_file_path)

print(f"算例运行时间：{execution_time}秒")
